package nccloud.riart.bs.bgplugin;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import com.alibaba.fastjson.JSONObject;

import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.bs.pub.pa.PreAlertObject;
import nc.bs.pub.taskcenter.BgWorkingContext;
import nc.bs.pub.taskcenter.IBackgroundWorkPlugin;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.BeanListProcessor;
import nc.jdbc.framework.processor.MapProcessor;
import nc.vo.am.common.util.CollectionUtils;
import nc.vo.pf.worknote.WorkNoteVO;
import nc.vo.pub.BusinessException;
import nccloud.riart.pub.utils.OAHttpClientUtils;
import nccloud.riart.pub.utils.OAUrlUtils;
import nccloud.riart.pub.utils.QueryDatabaseUtils;

public class PendingTrialPeopleBgPlugin implements IBackgroundWorkPlugin {

	// 调用NCC系统单点登录系统的基础URL
	private static final String BASE_APPROVE_URL = "/nccloud/sso/visit.action?";
	private static final String BASE_APPROVE_URL_MOB = "/nccloud/resources/mobile_plan/app/baseData/main/#/msgcenter/AllMsg?isApprove=N";
	private BaseDAO dao = new BaseDAO();

	/**
	 * 逻辑控制中心
	 */
	@Override
	public PreAlertObject executeTask(BgWorkingContext context) throws BusinessException {

		nc.bs.logging.Logger.error("PendingTrial ----- 开始执行待办推送");
		List<WorkNoteVO> unapproveBillList = this.getUnapproveBill(); 
		if (CollectionUtils.isNotEmpty(unapproveBillList)) { 
			try {
				//请求微信token  
				String wxtokenret = OAHttpClientUtils.reqWX_Token();
				nc.bs.logging.Logger.error("PendingTrial ----- wxtokenret: "+wxtokenret);
				JSONObject wxtokenjson = new JSONObject();
				String wxtoken = "";
				if(null!=wxtokenret && !"".equals(wxtokenret)){
					wxtokenjson= (JSONObject) JSONObject.parse(wxtokenret);
					wxtoken = wxtokenjson.getString("access_token");
				}
				
				nc.bs.logging.Logger.error("PendingTrial ----- unapproveBillList: "+unapproveBillList.size());
				
				for (WorkNoteVO workNoteVO : unapproveBillList) { 
					String wxresult = null; 
					String result = null;
					// 转为请求OA接口的数据格式
					Map<String,String> mapData = this.unapproveBillsToOAToDO(workNoteVO);
					
					
					//test环境 只发送用户编码为testhr的数据，正式环境需要删除
//					String receiverCode = QueryDatabaseUtils.getCodeByUserPk(workNoteVO.getCheckman());
//					nc.bs.logging.Logger.error("PendingTrial ----- receiverCode: "+receiverCode);
//					if(null==receiverCode || !"testhr".equals(receiverCode) ) {
//						continue;
//					}
					//test环境 只发送用户编码为testhr的数据，正式环境需要删除
					
					// 请求接口获取返回结果
					if(mapData.get("oa")!=null) {
						nc.bs.logging.Logger.error("PendingTrial ----- oamapData: "+mapData.size());
						result = OAHttpClientUtils.reqOA_Task("batchReceiveUrl", mapData.get("oa"));
						nc.bs.logging.Logger.error("请求OA发送接口返回成功：" + result);
					}
					
					if(wxtoken!=null && !"".equals(wxtoken) && mapData.get("wx")!=null) {
						nc.bs.logging.Logger.error("PendingTrial ----- wxtokentoken: "+wxtoken);
						nc.bs.logging.Logger.error("PendingTrial ----- wxmapData: "+mapData.size());
						wxresult = OAHttpClientUtils.reqWX_Message(mapData.get("wx"), wxtoken);
						nc.bs.logging.Logger.error("请求WX发送接口返回成功：" + wxresult);
					}
					// 同步更新消息状态
					if(result!=null || wxresult!=null) {
						nc.bs.logging.Logger.error("PendingTrial ----- 同步更新消息状态开始 ");
						String oares=null;
						if(result!=null) {
							JSONObject retjson = (JSONObject) JSONObject.parse(result);
							oares = retjson.getString("result");
						}
						String wxres = null;
						String jobid = null;
						if(wxresult!=null) {
							JSONObject retjsonwx = (JSONObject) JSONObject.parse(wxresult);
							wxres = retjsonwx.getString("errmsg");
							jobid = retjsonwx.getString("jobid");
						}
						this.synNCCBills(workNoteVO,oares,wxres,jobid);
						nc.bs.logging.Logger.error("PendingTrial ----- 同步更新消息状态结束 ");
					}
				}
			} catch (Exception e) { 
				nc.bs.logging.Logger.error("PendingTrialError:" + e.getMessage());
				nc.bs.logging.Logger.error(e);
			}
		}
		return null;
	}

	/**
	 * 获取所有待办消息
	 * 
	 * @return
	 * @throws BusinessException
	 */
	@SuppressWarnings("unchecked")
	private List<WorkNoteVO> getUnapproveBill() throws BusinessException {
		IUAPQueryBS queryService = NCLocator.getInstance().lookup(IUAPQueryBS.class); 
		String queryWorkNoteSql = "select * from pub_workflownote where actiontype = 'Z' and approvestatus = 0 and (userObject is null or ciphertext is null)";
		List<WorkNoteVO> unapproveBillList = (List<WorkNoteVO>) queryService.executeQuery(queryWorkNoteSql,new BeanListProcessor(WorkNoteVO.class));
		return unapproveBillList;
	}

	/**
	 * 待办消息转为请求OA系统的VO数据
	 * 
	 * @param workNoteVO
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private Map<String,String> unapproveBillsToOAToDO(WorkNoteVO workNoteVO) throws Exception {
		
		Map retmap = new HashMap<String,String>();
		BaseDAO baseDao = new BaseDAO();
		if (null != workNoteVO) {
			String querySql = "select ap.billid,"
					+ " ap.billno, "
					+ " ap.pk_message, "
					+ " ap.msgsourcetype, "
					+ " ap.subject, "
					+ " ap.sendtime, "
					+ " bt.billtypename, "
					+ " rp.appcode, "
					+ " rp.pagecode,"
					+ " bt.pk_billtypecode, "
					+ " wf.ciphertext as wxjobid, "
					+ " wf.userobject as oastatus "
					+ " from sm_msg_approve ap,pub_workflownote wf, bd_billtype bt, bd_relatedapp rp " 
					+ " where ap.pk_detail = '" + workNoteVO.getPk_checkflow() + "'"
					+ " and ap.pk_detail=wf.pk_checkflow "
					+ " and bt.pk_billtypecode = ap.billtype "
					+ " and ((rp.pk_billtypecode = bt.parentbilltype) or (rp.pk_billtypecode=bt.pk_billtypecode)) "
					+ " and rp.pagecode is not null "
					+ " and ( nvl ( rp.dr, 0 ) = 0 ) and rp.sence = 3 and rp.priority<10 "; 
			Map<String, String> resultMap = (Map<String, String>) baseDao.executeQuery(querySql, new MapProcessor());
			// 如果为空则需要重新查询 
			if (null == resultMap || resultMap.size() == 0) {
				querySql = "   select distinct ap.billid," + 
						"       ap.billno," + 
						"       ap.pk_message," + 
						"       ap.msgsourcetype," + 
						"       ap.subject," + 
						"       ap.sendtime," + 
						"       bt.billtypename," + 
						"       bt.parentbilltype," + 
						"       rp.appcode," + 
						"       rp.pagecode," + 
						"       bt.pk_billtypecode," + 
						"       wf.ciphertext as wxjobid," + 
						"       wf.userobject as oastatus" + 
						"  from sm_msg_approve ap,pub_workflownote wf, bd_billtype bt,bd_relatedapp rp" + 
						"  where ap.pk_detail = '"+workNoteVO.getPk_checkflow()+"'" + 
						"   and ap.pk_detail = wf.pk_checkflow"+
						"   and bt.pk_billtypecode = ap.billtype" + 
						"   and ((rp.pk_billtypecode = bt.parentbilltype) or (rp.pk_billtypecode=bt.pk_billtypecode)) " +
						"   and (nvl(rp.dr, 0) = 0) and rp.sence = 3 and rp.priority<10 " + 
						"   order by rp.pagecode asc";
				resultMap = (Map<String, String>) baseDao.executeQuery(querySql, new MapProcessor());
			}
			// 如果为空则需要重新查询
			if (null == resultMap || resultMap.size() == 0) {
				querySql = "select ap.billid," + 
						"       ap.billno," + 
						"       ap.pk_message," + 
						"       ap.msgsourcetype," + 
						"       ap.subject," + 
						"       ap.sendtime," + 
						"       bt.billtypename," + 
						"       regis.code appcode," + 
						"       pub.pagecode," + 
						"       bt.pk_billtypecode," + 
						"       wf.ciphertext as wxjobid," + 
						"       wf.userobject as oastatus," + 
						"       pub.sence" + 
						"  from sm_msg_approve ap,pub_workflownote wf, bd_billtype bt, pub_publishapp pub, sm_appregister regis" + 
						" where ap.pk_detail = '"+workNoteVO.getPk_checkflow()+"'" + 
						"   and ap.pk_detail = wf.pk_checkflow"+
						"   and bt.pk_billtypecode = ap.billtype" + 
						"   and pub.pk_billtypecode = bt.pk_billtypecode" + 
						"   and pub.publishappid = regis.pk_appregister" + 
						"   and (nvl(pub.dr, 0) = 0) and pub.sence = 3" + 
						"   order by pub.pagecode asc";
				resultMap = (Map<String, String>) baseDao.executeQuery(querySql, new MapProcessor());
			}
			
			if (null != resultMap && resultMap.size() > 0) {
				if(resultMap.get("oastatus")==null) {
					String sendJson = generateSendData(workNoteVO, resultMap);
					retmap.put("oa", sendJson);
				}
				if(resultMap.get("wxjobid")==null) {
					String sendWXJson = generateSendDataWX(workNoteVO, resultMap);
					retmap.put("wx", sendWXJson);
				}
			}
		}
		return retmap;
	}

	/**
	 * 拼接及赋值OA
	 * @param workNoteVO
	 * @param resultMap
	 * @return
	 * @throws Exception
	 */
	private String generateSendData( WorkNoteVO workNoteVO,
			Map<String, String> resultMap) throws Exception {
		
		String pk_message = resultMap.get("pk_message");
		String appcode = resultMap.get("appcode");
		String pagecode = resultMap.get("pagecode");
		String pk_billtypecode = resultMap.get("pk_billtypecode");
		String subject = resultMap.get("subject");
		String receiverCode = QueryDatabaseUtils.getCodeByUserPk(workNoteVO.getCheckman());
		String billid = resultMap.get("billid");
		String billno = resultMap.get("billno");
		
		if(pagecode==null) {
			nc.bs.logging.Logger.error("单据类型【"+ pk_billtypecode + "】未关联应用编码，请在单据类型管理处设置！");
			throw new BusinessException("单据类型【"+ pk_billtypecode + "】未关联应用编码，请在单据类型管理处设置！");
		}

		// 参数列表
		StringBuilder desBuilder = new StringBuilder();
		desBuilder.append("pk_message=").append(pk_message).append("&pk_bill=").append(billid).append("&billno=").append(billno)
		.append("&c=").append(appcode).append("&p=").append(pagecode).append("&usercode=").append(receiverCode);
		
		Properties nccProperties= OAUrlUtils.getNccUrlInfo();
		String pcUrl = "http://" + nccProperties.get("ip") + ":" + nccProperties.get("port") + BASE_APPROVE_URL + desBuilder.toString();
		
		String urlData = "";
		urlData += "TaskName=" + subject;
		urlData += "&TaskExecutor=" + receiverCode;
//		urlData += "&TaskExecutor=" + "zheng_z";
		urlData += "&TaskType=" + "网上表单";
		urlData += "&WrkID=" + pk_message;
		urlData += "&KeyID=" + pk_message;
		urlData += "&ExecURL=" + URLEncoder.encode(pcUrl);
		
//		JSONObject jsobj = new JSONObject();
//	    jsobj.put("TaskName", subject);
//	    jsobj.put("TaskExecutor", "zheng_z");
//	    jsobj.put("TaskExecutor", receiverCode);
//	    jsobj.put("TaskType", "网上表单");
//	    jsobj.put("WrkID", pk_message);//任务id
//	    jsobj.put("KeyID", pk_message);//整个流程id
//	    jsobj.put("ExecURL", pcUrl);
//		return jsobj.toJSONString();
		return urlData;
	}

	/**
	 * 拼接及赋值WX
	 * @param workNoteVO
	 * @param resultMap
	 * @return
	 * @throws Exception
	 */
	private String generateSendDataWX( WorkNoteVO workNoteVO,
			Map<String, String> resultMap) throws Exception {
		
		JSONObject jsobj = new JSONObject();
		
		String subject = resultMap.get("subject");
		String receiverCode = QueryDatabaseUtils.getCodeByUserPk(workNoteVO.getCheckman());
		String billno = resultMap.get("billno");
		
		Properties nccProperties= OAUrlUtils.getNccUrlInfo();
		String nccip = (String) nccProperties.get("ip");
		String nccport = (String) nccProperties.get("port");
		String busicode = (String) nccProperties.get("busicentercode");
		
		// 参数列表
		StringBuilder desBuilder = new StringBuilder();
		desBuilder.append("&usercode=").append(receiverCode).append("&busicode=").append(busicode).append("&billno=").append(billno);
		String mobUrl = "http://" + nccip + ":" + nccport + BASE_APPROVE_URL_MOB + desBuilder.toString();

	    jsobj.put("touser", receiverCode);
	    jsobj.put("toparty", "");
	    jsobj.put("totag", "");
	    jsobj.put("msgtype", "text");
	    jsobj.put("agentid", 1000006);
	    
	    String msgContent = null;
	    msgContent = "你有一条来自NCC系统的审批待办消息，请及时处理。<br>" + "<a href='" + mobUrl + "'>" + subject + "</a>";
	    JSONObject jscontent = new JSONObject();
	    jscontent.put("content", msgContent);
	    jsobj.put("text", jscontent);
		
		return jsobj.toJSONString();
	}

	private void synNCCBills(WorkNoteVO workNoteVO,String oaresult,String wxresult,String wxjobid) throws BusinessException {
		nc.bs.logging.Logger.error("PendingTrial ----- 执行数据库操作");
		String oaupdstr="~";
		String wxupdstr="~";
		String pk_checkflow = workNoteVO.getPk_checkflow();
		if (null != workNoteVO && "success".equals(oaresult)) {
			oaupdstr="已推送";
			String updatesql = "update pub_workflownote set userObject = '已推送'  where pk_checkflow = '" + pk_checkflow + "'";
			dao.executeUpdate(updatesql);
		}
		if (null != workNoteVO && "ok".equals(wxresult)) {
			//如果微信发送成功，更新微信jobid
			if(wxjobid!=null) {
				wxupdstr=wxjobid;
				String updatesqlWX = "update pub_workflownote set ciphertext = '" + wxjobid + "'  where pk_checkflow = '" + pk_checkflow + "'";
				dao.executeUpdate(updatesqlWX);
			}
		}
		//更新sm_msg_approve表，删除时用
		String updstr=oaupdstr+"#"+wxupdstr;
		String updatesqlWXEx = "update sm_msg_approve set message_service = '" + updstr + "' where pk_detail = '" + pk_checkflow + "'";
		dao.executeUpdate(updatesqlWXEx);
	}
}
